package j2EE.servlet;

import j2EE.io.CacheOutputStream;
import org.apache.catalina.core.ApplicationContext;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.*;

/**
 * Created with Intel IDEA.
 * 响应包装器 重载了原始的getOutputStream 和 getWriter , 以返回CacheOutputStream
 * 相当于装饰器模式
 * @Auther: gjt
 * @Date: 2024/9/1 14:12
 */
public class XSLTResponseWrapper extends HttpServletResponseWrapper {
    // 原始响应
    private HttpServletResponse orgig;

    private PrintWriter writer;
    private ServletOutputStream stream;

    // xml转换过滤器的名称
    private String transform;

    // 输出页面是否为xml
    private boolean isXML = false;

    // 保存转换文件和原始结果
    public XSLTResponseWrapper(HttpServletResponse response, String transform) {
        super(response);
        orgig = response;
        this.transform = transform;
    }
    // 创建输出流 - 如果响应码已被编码，则将其保存用于以后转换，否则使用默认流即可

    public ServletOutputStream createOutPutStream() throws IOException {
        if (this.containsHeader("XML-Encoded")) {
            isXML = true;
            return new CacheOutputStream();
        } else {
            return orgig.getOutputStream();
        }
    }

    // 返回输出流 - 如果getWriter() 以前被调用过， 则将失败
    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        if (stream != null) return stream;
        if (writer != null) throw new IOException("getWriter() already called");
        stream = createOutPutStream();
        return stream;
    }

    // 返回一个Writer - 如果getOutPutStream() 以前被调用过， 则将失败
    @Override
    public PrintWriter getWriter() throws IOException {
        if (writer != null) return writer;

        if (stream != null) throw new IOException("getOutputStream() already called");
        writer = new PrintWriter(new OutputStreamWriter(createOutPutStream()));
        return writer;
    }

    // 油过滤器调用来执实际的XML转换， 如果数据不是XML 则立即返回
    public void writeResponse() throws IOException {
        if (!isXML) return;

//        ServletContext sc = filterConfig.getServletContest();
        ServletContext sc = null;
        sc.log("XSLTFilter:writeXML");

        if (stream == null) throw new IOException("No stream to commit");

//        InputStream is = ((CacheOutputStream) stream).getInputStream();
        InputStream is = new BufferedInputStream(new BufferedInputStream(new FileInputStream("ssss")));
        // 执行实际转换
        try {
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();

            // 读取缓存中的响应数据
            Document document = documentBuilder.parse(is);

            // 应用转换
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            StreamSource streamSource = new StreamSource(sc.getResourceAsStream(transform));

            Transformer transformer = transformerFactory.newTransformer(streamSource);
            DOMSource domSource = new DOMSource(document);

            // 向原始输出流发送结果
            StreamResult streamResult = new StreamResult(orgig.getOutputStream());
            transformer.transform(domSource, streamResult);

        } catch (ParserConfigurationException | SAXException | TransformerException e) {
            sc.log("Error Transforming", e);
            throw new RuntimeException(e);
        }
    }
}
